home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Linux / Kubuntu 8.10 / kubuntu-8.10-desktop-i386.iso / casper / filesystem.squashfs / usr / sbin / update-xmlcatalog < prev    next >
Text File  |  2008-10-14  |  17KB  |  632 lines

  1. #!/usr/bin/perl
  2. ## ----------------------------------------------------------------------
  3. ## Debian update-xmlcatalog
  4. ## ----------------------------------------------------------------------
  5. ## Copyright (c) 2003-2004 Ardo van Rangelrooij
  6. ##
  7. ## This is free software; see the GNU General Public Licence version 2
  8. ## or later for copying conditions.  There is NO warranty.
  9. ## ----------------------------------------------------------------------
  10.  
  11. =head1 NAME
  12.  
  13. update-xmlcatalog - maintain XML catalog files
  14.  
  15. =head1 SYNOPSIS
  16.  
  17. B<update-xmlcatalog> B<--add> B<--root> S<B<--package> I<package>>
  18. S<B<--type> I<type>> S<B<--id> I<id>>
  19.  
  20. B<update-xmlcatalog> B<--del> B<--root> S<B<--package> I<package>>
  21. S<B<--type> I<type>> S<B<--id> I<id>>
  22.  
  23. B<update-xmlcatalog> B<--add> S<B<--package> I<package>> S<B<--local>
  24. I<local>> S<B<--type> I<type>> S<B<--id> I<id>>
  25.  
  26. B<update-xmlcatalog> B<--del> S<B<--package> I<package>> S<B<--local>
  27. I<local>> S<B<--type> I<type>> S<B<--id> I<id>>
  28.  
  29. B<update-xmlcatalog> B<--add> S<B<--local> I<local>> S<B<--file>
  30. I<file>> S<B<--type> I<type>> S<B<--id> I<id>>
  31.  
  32. B<update-xmlcatalog> B<--del> S<B<--local> I<local>> S<B<--file>
  33. I<file>> S<B<--type> I<type>> S<B<--id> I<id>>
  34.  
  35. B<update-xmlcatalog> B<--help>
  36.  
  37. =head1 DESCRIPTION
  38.  
  39. B<update-xmlcatalog> add entries to and removes entries from the root
  40. XML catalog file, a package XML catalog file or a local XML catalog
  41. file.
  42.  
  43. =head1 OPTIONS
  44.  
  45. =over 4
  46.  
  47. =item B<--add>
  48.  
  49. Adds the entry to the root XML catalog file, a package XML catalog
  50. file or a local XML catalog file.  If the XML catalog file does not
  51. exist yet, it is automatically created.
  52.  
  53. =item B<--del>
  54.  
  55. Deletes the entry from the root XML catalog file, the package XML
  56. catalog file or the local XML catalog file.  A resulting empty XML
  57. catalog is not automatically deleted from the filesystem.
  58.  
  59. =item B<--file> I<file>
  60.  
  61. Indicates a local filename.
  62.  
  63. =item B<--id> I<id>
  64.  
  65. Indicates the XML catalog file entry identifier.
  66.  
  67. =item B<--local> I<local>
  68.  
  69. Indicates a local XML catalog file.
  70.  
  71. =item B<--package> I<package>
  72.  
  73. Indicates a package XML catalog file.
  74.  
  75. =item B<--root>
  76.  
  77. Indicates the root XML catalog file.
  78.  
  79. =item B<--type> I<type>
  80.  
  81. Indicates the XML catalog file entry type (public, system, uri).
  82.  
  83. =item B<--help>
  84.  
  85. Displays the usage information.
  86.  
  87. =back
  88.  
  89. =head1 NOTES
  90.  
  91. B<update-xmlcatalog> is the de-facto standard tool to be used to
  92. maintain XML catalog files on a Debian system, similar to that
  93. L<update-catalog(8)> is the standard tool to be used to main SGML
  94. catalog files on a Debian system.  A Debian XML Policy document to
  95. this effect is currently under development.
  96.  
  97. B<update-xmlcatalog> and L<xmlcatalog(1)> are incompatible.  The
  98. former has an internal database of all the entries in all the XML
  99. catalog files it maintains and regenerates the indicated XML catalog
  100. file completely from scratch upon an update.  The latter updates the
  101. indicated XML catalog file directly.  This means that any change made
  102. to an XML catalog file using L<xmlcatalog(1)> is overwritten the next
  103. time that XML catalog file is updated using B<update-xmlcatalog>.
  104.  
  105. =head1 SEE ALSO
  106.  
  107. F</usr/share/doc/xml-core/README.Debian>
  108.  
  109. =head1 AUTHOR
  110.  
  111. =over 0
  112.  
  113. =item
  114. Ardo van Rangelrooij <ardo@debian.org>
  115.  
  116. =back
  117.  
  118. =cut
  119.  
  120. ## ----------------------------------------------------------------------
  121. use strict;
  122.  
  123. ## ----------------------------------------------------------------------
  124. use File::Spec;
  125. use Getopt::Long;
  126.  
  127. ## ----------------------------------------------------------------------
  128. $0  =~ m|[^/]+$|;
  129.  
  130. ## ----------------------------------------------------------------------
  131. my $name = $&;
  132.  
  133. ## ----------------------------------------------------------------------
  134. use vars qw( $catalog_data $catalog_data_dir );
  135. use vars qw( $catalog $catalog_dir );
  136. use vars qw( %catalog $key $entry );
  137.  
  138. ## ----------------------------------------------------------------------
  139. $catalog_data_dir = '/var/lib/xml-core';
  140. $catalog_dir      = '/etc/xml';
  141.  
  142. ## ----------------------------------------------------------------------
  143. use vars qw( $add );
  144. use vars qw( $del );
  145. use vars qw( $file );
  146. use vars qw( $help );
  147. use vars qw( $local );
  148. use vars qw( $package );
  149. use vars qw( $root );
  150. use vars qw( $type $id );
  151. use vars qw( $verbose );
  152.  
  153. ## ----------------------------------------------------------------------
  154. if ( ! GetOptions(
  155.           'add'       => \$add,
  156.           'del'       => \$del,
  157.           'file=s'    => \$file,
  158.           'help'      => \$help,
  159.           'id=s'      => \$id,
  160.           'local=s'   => \$local,
  161.           'package=s' => \$package,
  162.           'root'      => \$root,
  163.           'type=s'    => \$type,
  164.           'verbose'   => \$verbose,
  165.           )
  166.      )
  167. {
  168.     &help;
  169.     exit 1;
  170. }
  171.  
  172.  
  173. ## ----------------------------------------------------------------------
  174. if ( defined( $help ) )
  175. {
  176.     &help;
  177.     exit -1;
  178. }
  179.  
  180. ## ----------------------------------------------------------------------
  181. if  ( ! ( defined( $add ) || defined( $del ) ) )
  182. {
  183.     print STDERR "$name: error: either 'add' or 'del' must be given\n";
  184.     exit 1;
  185. }
  186. elsif  ( ( defined( $add ) && defined( $del ) ) )
  187. {
  188.     print STDERR "$name: error: only one of 'add' and 'del' can be given\n";
  189.     exit 1;
  190. }
  191.  
  192. ## ----------------------------------------------------------------------
  193. if ( defined( $add ) )
  194. {
  195.     if ( defined( $root ) )
  196.     {
  197.     if ( defined( $package ) )
  198.     {
  199.         my $catalog = File::Spec->catfile( $catalog_dir, "$package.xml" );
  200.         if ( ! -f $catalog )
  201.         {
  202.         print STDERR "$name: error: package catalog $catalog not found\n";
  203.         exit 1;
  204.         }
  205.     }
  206.     else
  207.     {
  208.         print STDERR "$name: error: package catalog not given\n";
  209.         exit 1;
  210.     }
  211.     if ( defined( $local) || defined( $file ) )
  212.     {
  213.         print STDERR "$name: error: local catalog and file not for adding to root catalog file\n";
  214.         exit 1;
  215.     }
  216.     }
  217.     elsif ( defined( $package ) )
  218.     {
  219.     if ( defined( $local ) )
  220.     {
  221.         if ( ! -f $local )
  222.         {
  223.         print STDERR "$name: error: local catalog $local not found\n";
  224.         exit 1;
  225.         }
  226.     }
  227.     else
  228.     {
  229.         print STDERR "$name: error: local catalog not given\n";
  230.         exit 1;
  231.     }
  232.     if ( defined( $file ) )
  233.     {
  234.         print STDERR "$name: error: file not for adding to package catalog file\n";
  235.         exit 1;
  236.     }
  237.     }
  238.     elsif ( defined( $local ) )
  239.     {
  240.     if ( defined( $file ) )
  241.     {
  242.         if ( ! -f $file )
  243.         {
  244.         print STDERR "$name: error: file $file not found\n";
  245.         exit 1;
  246.         }
  247.     }
  248.     else
  249.     {
  250.         print STDERR "$name: error: file not given\n";
  251.         exit 1;
  252.     }
  253.     }
  254.     else
  255.     {
  256.     print STDERR "$name: error: catalog not given\n";
  257.     exit 1;
  258.     }
  259. }
  260. elsif ( defined( $del ) )
  261. {
  262.     if ( defined( $root ) )
  263.     {
  264.     my $catalog = File::Spec->catfile( $catalog_dir, 'catalog' );
  265.     if ( ! -f $catalog )
  266.     {
  267.         print STDERR "$name: error: root catalog $catalog not found\n";
  268.         exit 1;
  269.     }
  270.     if ( defined( $package) || defined( $local ) || defined( $file ) )
  271.     {
  272.         print STDERR "$name: error: package catalog, local catalog or file not for deleting from root catalog file\n";
  273.         exit 1;
  274.     }
  275.     }
  276.     elsif ( defined( $package ) )
  277.     {
  278.     my $catalog = File::Spec->catfile( $catalog_dir, "$package.xml" );
  279.     if ( ! -f $catalog )
  280.     {
  281.         print STDERR "$name: error: package catalog $catalog not found\n";
  282.         exit 1;
  283.     }
  284.     if ( defined( $local ) || defined( $file ) )
  285.     {
  286.         print STDERR "$name: error: local catalog or file not for deleting from package catalog file\n";
  287.         exit 1;
  288.     }
  289.     }
  290.     elsif ( defined( $local ) )
  291.     {
  292.     if ( ! -f $local )
  293.     {
  294.         print STDERR "$name: error: local catalog $local not found\n";
  295.         exit 1;
  296.     }
  297.     if ( defined( $file ) )
  298.     {
  299.         print STDERR "$name: error: file not for deleting from local catalog file\n";
  300.         exit 1;
  301.     }
  302.     }
  303.     else
  304.     {
  305.     print STDERR "$name: error: catalog not given\n";
  306.     exit 1;
  307.     }
  308. }
  309.  
  310. ## ----------------------------------------------------------------------
  311. if ( defined( $type ) )
  312. {
  313.     if ( $type !~ /^(public|system|uri)$/ )
  314.     {
  315.         print STDERR "$name: error: wrong type\n";
  316.         exit 1;
  317.     }
  318. }
  319. else
  320. {
  321.     print STDERR "$name: error: type not given\n";
  322.     exit 1;
  323. }
  324.  
  325. ## ----------------------------------------------------------------------
  326. if ( ! defined( $id ) )
  327. {
  328.     print STDERR "$name: error: id not given\n";
  329.     exit 1;
  330. }
  331.  
  332. ## ----------------------------------------------------------------------
  333. if ( defined( $root ) )
  334. {
  335.     $catalog = 'catalog';
  336.     $catalog_data = File::Spec->catfile( $catalog_data_dir, $catalog );
  337.     $catalog = File::Spec->catfile( $catalog_dir, $catalog );
  338.     my $start = $type;
  339.     $start .= 'Id' unless $type eq 'uri';
  340.     $start .= 'StartString';
  341.     $id = "$start=\"$id\"";
  342.     $type = ( $type eq 'uri' ) ? "\U$type" : "\u$type";
  343.     $type = "delegate$type";
  344.     $package = "catalog=\"file:///etc/xml/$package.xml\"";
  345.     $key = "$type $id";
  346.     $entry = "$package";
  347. }
  348. elsif ( defined( $package ) )
  349. {
  350.     $catalog_data = File::Spec->catfile( $catalog_data_dir, $package );
  351.     $catalog = File::Spec->catfile( $catalog_dir, "$package.xml" );
  352.     my $start = $type;
  353.     $start .= 'Id' unless $type eq 'uri';
  354.     $start .= 'StartString';
  355.     $id = "$start=\"$id\"";
  356.     $type = ( $type eq 'uri' ) ? "\U$type" : "\u$type";
  357.     $type = "delegate$type";
  358.     $local = "catalog=\"file://$local\"";
  359.     $key = "$type $id";
  360.     $entry = "$local";
  361. }
  362. elsif ( defined( $local ) )
  363. {
  364.     $catalog = $local;
  365.     $catalog_data = $local;
  366.     $catalog_data =~ tr|/|_|;
  367.     $catalog_data = File::Spec->catfile( $catalog_data_dir, $catalog_data );
  368.     my $start = ( $type eq 'uri' ) ? 'name' : $type;
  369.     $start .= 'Id' unless $type eq 'uri';
  370.     $id = "$start=\"$id\"";
  371.     $file = "uri=\"$file\"";
  372.     $key = "$type $id";
  373.     $entry = "$file";
  374. }
  375.  
  376. ## ----------------------------------------------------------------------
  377. if ( defined( $add ) )
  378. {
  379.     &read_catalog_data if -f $catalog_data;
  380.     if ( &add_entry )
  381.     {
  382.     &create_backup if -f $catalog;
  383.     &write_catalog_data;
  384.     &write_catalog;
  385.     }
  386.     else
  387.     {
  388.     exit 1;
  389.     }
  390. }
  391. elsif ( defined( $del ) )
  392. {
  393.     &read_catalog_data;
  394.     if ( &del_entry )
  395.     {
  396.     &create_backup;
  397.     &write_catalog_data;
  398.     &write_catalog;
  399.     }
  400.     else
  401.     {
  402.     exit 1;
  403.     }
  404. }
  405.  
  406. ## ----------------------------------------------------------------------
  407. exit 0;
  408.  
  409. ## ----------------------------------------------------------------------
  410. sub add_entry
  411. {
  412.  
  413.     ## ------------------------------------------------------------------
  414.     if ( exists( $catalog{ $key } ) )
  415.     {
  416.     if ( $catalog{ $key } ne $entry )
  417.     {
  418.         print STDERR "$name: Error: entity already registered with a different value\n";
  419.         print STDERR " Entity   : [$key]\n";
  420.         print STDERR " Old value: [$catalog{$key}]\n";
  421.         print STDERR " New value: [$entry]\n";
  422.         return;
  423.     }
  424.     else
  425.     {
  426.         print STDERR "$name: notice: entity already registered with the same value\n"
  427.         if $verbose;
  428.         return 1;
  429.     }
  430.     }
  431.     else
  432.     {
  433.     print "$name: adding entity to catalog data $catalog_data\n"
  434.         if $verbose;
  435.     $catalog{ $key } = $entry;
  436.     return 1;
  437.     }
  438.  
  439. } ## add_entry
  440.  
  441. ## ----------------------------------------------------------------------
  442. sub del_entry
  443. {
  444.  
  445.     ## ------------------------------------------------------------------
  446.     if ( exists( $catalog{ $key } ) )
  447.     {
  448.     print "$name: removing entity from catalog data $catalog_data\n"
  449.         if $verbose;
  450.     delete( $catalog{ $key } );
  451.     return 1;
  452.     }
  453.     else
  454.     {
  455.     print STDERR "$name: error: entity not registered\n";
  456.     return;
  457.     }
  458.  
  459. } ## del_entry
  460.  
  461. ## ----------------------------------------------------------------------
  462. sub read_catalog_data
  463. {
  464.  
  465.     ## ------------------------------------------------------------------
  466.     print "$name: reading catalog data $catalog_data\n" if $verbose;
  467.     open( CATALOG_DATA, '<', $catalog_data )
  468.     or die "$name: cannot open catalog data $catalog_data for reading: $!";
  469.     while ( <CATALOG_DATA> )
  470.     {
  471.     chop;
  472.     my ( $key, $entry ) = split( />/ );
  473.     $key =~ s/^<//;
  474.     $entry =~ s/^<//;
  475.     $catalog{ $key } = $entry;
  476.     }
  477.     close( CATALOG_DATA )
  478.     or die "$name: cannot close catalog data $catalog_data: $!";
  479.  
  480. } ## read_catalog_data
  481.  
  482. ## ----------------------------------------------------------------------
  483. sub write_catalog_data
  484. {
  485.  
  486.     ## ------------------------------------------------------------------
  487.     print "$name: writing catalog data $catalog_data\n" if $verbose;
  488.     open( CATALOG_DATA, '>', $catalog_data )
  489.     or die "$name: cannot open catalog data $catalog_data for writing: $!";
  490.     my $counter = 0;
  491.     for my $key ( keys %catalog )
  492.     {
  493.     print( CATALOG_DATA "<$key><$catalog{ $key }>\n" );
  494.     $counter++;
  495.     }
  496.     close( CATALOG_DATA )
  497.     or die "$name: cannot close catalog data $catalog_data: $!";
  498.  
  499.     ## ------------------------------------------------------------------
  500.     if ( $counter == 0 )
  501.     {
  502.     print "$name: removing catalog data $catalog_data\n" if $verbose;
  503.     unlink( $catalog_data );
  504.     }
  505.  
  506. } ## write_catalog_data
  507.  
  508. ## ----------------------------------------------------------------------
  509. sub create_backup
  510. {
  511.  
  512.     ## ------------------------------------------------------------------
  513.     my $backup = $catalog . '.old';
  514.  
  515.     ## ------------------------------------------------------------------
  516.     if ( -f $backup )
  517.     {
  518.     print "$name: removing backup $backup\n" if $verbose;
  519.     unlink( $backup )
  520.         or die "$name: cannot remove backup $backup: $!";
  521.     }
  522.  
  523.     ## ------------------------------------------------------------------
  524.     print "$name: moving catalog $catalog to backup $backup\n" if $verbose;
  525.     rename( $catalog, $backup )
  526.     or die "$name: cannot move catalog $catalog to backup $backup: $!";
  527.  
  528. } ## create_backup
  529.  
  530. ## ----------------------------------------------------------------------
  531. sub write_catalog
  532. {
  533.  
  534.     ## ------------------------------------------------------------------
  535.     my @catalog = ();
  536.  
  537.     ## ------------------------------------------------------------------
  538.     my $header = '/usr/share/xml-core/catalog.header';
  539.     open( HEADER, '<', $header )
  540.     or die "$name: cannot open catalog header $header for reading: $!";
  541.     while ( <HEADER> )
  542.     {
  543.     chop;
  544.     push( @catalog, $_ );
  545.     }
  546.     close( HEADER )
  547.     or die "$name: cannot close catalog header $header: $!";
  548.  
  549.     ## ------------------------------------------------------------------
  550.     my $counter = 0;
  551.     for my $key ( keys %catalog )
  552.     {
  553.     push( @catalog, "<$key $catalog{ $key }/>" );
  554.     $counter++;
  555.     }
  556.  
  557.     ## ------------------------------------------------------------------
  558.     my $footer = '/usr/share/xml-core/catalog.footer';
  559.     open( FOOTER, '<', $footer )
  560.     or die "$name: cannot open catalog footer $footer for reading: $!";
  561.     while ( <FOOTER> )
  562.     {
  563.     chop;
  564.     push( @catalog, $_ );
  565.     }
  566.     close( FOOTER )
  567.     or die "$name: cannot close catalog footer $footer: $!";
  568.  
  569.     ## ------------------------------------------------------------------
  570.     print "$name: writing catalog $catalog\n" if $verbose;
  571.     open( CATALOG, '>', $catalog )
  572.     or die "$name: cannot open catalog $catalog for writing: $!";
  573.     for ( @catalog )
  574.     {
  575.     print( CATALOG $_, "\n" );
  576.     }
  577.     close( CATALOG )
  578.     or die "$name: cannot close catalog $catalog: $!";
  579.  
  580.     ## ------------------------------------------------------------------
  581.     if ( $counter == 0 )
  582.     {
  583.     print "$name: removing catalog $catalog\n" if $verbose;
  584.     unlink( $catalog );
  585.     }
  586.  
  587. } ## write_catalog
  588.  
  589. ## ----------------------------------------------------------------------
  590. sub help
  591. {
  592.  
  593.     ## ------------------------------------------------------------------
  594.     print <<END;
  595. Usage:
  596.     $name <options> --add --root --type <type> \\
  597.                                                 --id <id> --package <package>
  598.     $name <options> --del --root --type <type> \\
  599.                                                 --id <id>
  600.  
  601.     $name <options> --add --package <package> --type <type> \\
  602.                                                 --id <id> --local <local>
  603.     $name <options> --del --package <package> --type <type> \\
  604.                                                 --id <id>
  605.  
  606.     $name <options> --add --local <local> --type <type> \\
  607.                                                 --id <id> --file <file>
  608.     $name <options> --del --local <local> --type <type> \\
  609.                                                 --id <id>
  610.  
  611.     $name --help
  612.  
  613. With:
  614.     --file <file>       = a local filename
  615.     --id <id>           = catalog entry idenitifier
  616.     --local <local>     = a local XML catalog
  617.     --package <package> = a package XML catalog
  618.     --root              = the root XML catalog (= /etc/xml/catalog)
  619.     --type <type>       = catalog entry type (= public, system, uri)
  620.  
  621. Options:
  622.     --verbose = be verbose
  623.  
  624. END
  625.  
  626. } ## help
  627.  
  628. ## ----------------------------------------------------------------------
  629. __END__
  630.  
  631. ## ----------------------------------------------------------------------
  632.